import cloneDeep from 'lodash/cloneDeep'
import type { RouteObject } from 'react-router-dom'
import { isEmpty, random } from 'lodash'
import { routes } from './index'
import { LocalStorageService } from "@/utils/storage";
import auth from "./permissions"

/**
 * 获取未处理的菜单项
 * 该函数旨在从根路由中提取特定的子菜单项，特别是那些id为'layout'的项
 * 这里使用了cloneDeep函数来深拷贝routes，以避免修改原始数据结构
 *
 * @returns {Array} 返回找到的子菜单项数组，如果没有找到则返回空数组
 */
function getNoDealMenu(): RouteObject[] {
  // 深拷贝routes，以避免修改原始数组
  const cloneroutes = cloneDeep(routes)

  // 返回第一个根路由的子菜单中id为'layout'的项的子菜单，如果没有找到则返回空数组
  return cloneroutes[0].children?.find(item => item.id === 'layout')?.children || []
}

/**
 * 递归生成所有子菜单
 * 此函数根据给定的路由对象数组和权限数组，过滤并生成一个新的路由对象数组，用于展示菜单
 * 它会忽略那些没有元数据且没有子菜单的项，同时根据用户的权限来过滤需要权限的菜单项
 *
 * @param noDealMenu 路由对象数组，尚未处理的菜单项
 * @param permissions 用户权限数组，用于检查菜单项是否可见
 * @returns 返回处理后的路由对象数组，仅包含那些应该展示在菜单中的项
 */
function generateallSubMenu(noDealMenu: RouteObject[], permissions: string[]) {
  // 存储处理后的菜单项
  const menus: RouteObject[] = []
  // 遍历每个菜单项
  for (const item of noDealMenu) {
    // 如果菜单项没有元数据且没有子菜单，则忽略它
    if (isEmpty(item.meta) && isEmpty(item.children))
      continue

    // 如果菜单项没有元数据但有子菜单，递归处理其子菜单
    if (isEmpty(item.meta) && !isEmpty(item.children)) {
      menus.push(...generateallSubMenu(item.children!, permissions))
      continue
    }

    // 复制当前菜单项，以便可能的修改
    const obj = {
      ...item,
    }

    // 如果菜单项有标题且不在菜单中隐藏
    if (item.meta?.title && !item.meta.hideInMenu) {
      // 如果菜单项需要权限，且用户没有相应的权限，则忽略它
      if (item.meta?.auth) {
        if ((typeof item.meta.auth === 'string' && !permissions.includes(item.meta.auth)) || (Array.isArray(item.meta.auth) && !item.meta.auth.some(v => permissions.includes(v))))
          continue
      }
      // 初始化菜单项的子菜单数组
      obj.children = []
      // 为菜单项生成一个唯一的键
      obj.onlyKey = item.path || random(0, 10, true).toString()
      // 将处理后的菜单项添加到菜单数组中
      menus.push(obj)

      // 如果菜单项有子菜单，递归处理其子菜单
      if (!isEmpty(item.children))
        obj.children.push(...generateallSubMenu(item.children!, permissions))
    }
  }


  // 返回处理后的菜单数组
  return menus
}

/**
 * 默认导出的函数LayoutLoader用于加载布局并处理菜单和权限
 * 此函数根据用户的权限和登录状态来确定展示哪些菜单项
 *
 * @returns { { permissions: string[]; allSubMenu: RouteObject[] }} 返回一个对象，包含权限、所有子菜单
 */
export default function LayoutLoader(): { permissions: string[]; allSubMenu: RouteObject[] } {
  // 初始化权限数组
  let permissions: string[] = []
  // 初始化所有子菜单数组
  let allSubMenu: RouteObject[] = []

  // 检查用户是否已登录
  if (LocalStorageService.get("token")) {
    // 根据用户权限获取权限列表
    permissions = auth
    // 获取未处理的菜单列表
    const noDealMenu = getNoDealMenu()
    // 根据用户权限生成所有子菜单
    allSubMenu = generateallSubMenu(noDealMenu, permissions)
  }

  // 返回权限、所有子菜单
  return {
    permissions,
    allSubMenu,
  }
}
